﻿using System;
using System.Collections.Generic;
using System.Xml;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.UI;
using YArchitech.HCLoad.Properties;
using YArchitech.HCLoad.Utils;
using YArchitech.Revit;

namespace YArchitech.HCLoad.Export
{
	public class HcDataManager
	{
		public List<Level> Levels
		{
			get
			{
				return this.m_levels;
			}
		}

		public Dictionary<ElementId, List<Space>> SpaceDictionary
		{
			get
			{
				return this.m_spaceDictionary;
			}
		}

		public Dictionary<ElementId, List<Zone>> ZoneDictionary
		{
			get
			{
				return this.m_zoneDictionary;
			}
		}

		public List<HcSpaceData> HcSpaces
		{
			get
			{
				return this.m_hcSpaces;
			}
		}

		public List<HcSurfaceData> HcSurfaces
		{
			get
			{
				return this.m_hcSurfaces;
			}
		}

		public Document Document
		{
			get
			{
				return this.m_document;
			}
		}

		public HcDataManager(Document doc)
		{
			this.m_document = doc;
			this.Initialize();
			ElementId elementId = this.m_document.ActiveView.get_Parameter(BuiltInParameter.VIEW_PHASE).AsElementId();
			YJKDocument hydocument = new YJKDocument(doc);
			this.m_defaultPhase = (hydocument.GetElement(elementId) as Phase);
		}

		public bool SetSpaceFilter(HcSpaceDataFilter spaceFilter)
		{
			this.m_spaceDataFilter = spaceFilter;
			return true;
		}

		private void Initialize()
		{
			this.m_levels = new List<Level>();
			this.m_spaceDictionary = new Dictionary<ElementId, List<Space>>();
			this.m_zoneDictionary = new Dictionary<ElementId, List<Zone>>();
			FilteredElementIterator elementIterator = new FilteredElementCollector(this.m_document).OfClass(typeof(Level)).GetElementIterator();
			FilteredElementIterator elementIterator2 = new FilteredElementCollector(this.m_document).WherePasses(new SpaceFilter()).GetElementIterator();
			FilteredElementIterator elementIterator3 = new FilteredElementCollector(this.m_document).OfClass(typeof(Zone)).GetElementIterator();
			elementIterator.Reset();
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				Level level = element as Level;
				if (level != null)
				{
					this.m_levels.Add(level);
					this.m_spaceDictionary.Add(level.Id, new List<Space>());
					this.m_zoneDictionary.Add(level.Id, new List<Zone>());
				}
			}
			this.m_levels.Sort(new SortLevel());
			elementIterator2.Reset();
			while (elementIterator2.MoveNext())
			{
				Element element2 = elementIterator2.Current;
				Space space = element2 as Space;
				if (space != null && !HcUtils.IsZero(space.Area) && null != space.ClosedShell && RevitVersionFuncs.GetGeometryObjectArray(space.ClosedShell).Count > 0)
				{
					this.m_spaceDictionary[space.LevelId].Add(space);
				}
			}
			elementIterator3.Reset();
			while (elementIterator3.MoveNext())
			{
				Element element3 = elementIterator3.Current;
				Zone zone = element3 as Zone;
				if (zone != null && zone.LevelId != null)
				{
					this.m_zoneDictionary[zone.LevelId].Add(zone);
				}
			}
		}

		public List<Space> GetSpaces(Level level)
		{
			return this.m_spaceDictionary[level.Id];
		}

		public List<Zone> GetZones(Level level)
		{
			return this.m_zoneDictionary[level.Id];
		}

		public bool Export(string sFileName)
		{
			this.ApplySpaceFilter();
			this.ObtainAllSurfaces();
			try
			{
				XmlDocument xmlDocument = new XmlDocument();
				XmlNode newChild = xmlDocument.CreateXmlDeclaration("1.0", "utf-8", null);
				xmlDocument.AppendChild(newChild);
				XmlElement newChild2 = xmlDocument.CreateElement("hcXML");
				new HcXmlRoot(this).WriteElementData(ref newChild2);
				xmlDocument.AppendChild(newChild2);
				xmlDocument.Save(sFileName);
				return true;
			}
			catch (Exception ex)
			{
				TaskDialog.Show(Resources.MSGBOX_TITLE, ex.Message);
			}
			return false;
		}

		private bool ObtainAllSurfaces()
		{
			this.m_hcSurfaces = new List<HcSurfaceData>();
			foreach (Level level in this.m_levels)
			{
				List<Space> spaces = this.GetSpaces(level);
				if (spaces != null && spaces.Count != 0)
				{
					foreach (Space space in spaces)
					{
						if (space != null && !(null == space.ClosedShell))
						{
							foreach (GeometryObject geometryObject in RevitVersionFuncs.GetGeometryObjectArray(space.ClosedShell))
							{
								Solid solid = geometryObject as Solid;
								if (!(null == solid))
								{
									foreach (object obj in solid.Faces)
									{
										PlanarFace planarFace = ((Face)obj) as PlanarFace;
										if (!(null == planarFace))
										{
											HcSurfaceData item = new HcSurfaceData(planarFace, space);
											this.m_hcSurfaces.Add(item);
										}
									}
								}
							}
						}
					}
				}
			}
			this.ObtainSurfaceData();
			return true;
		}

		private bool ObtainSurfaceData()
		{
			foreach (HcSurfaceData hcSurfaceData in this.m_hcSurfaces)
			{
				if (hcSurfaceData.ObtainHost())
				{
					Wall wall = hcSurfaceData.Host as Wall;
					if (wall != null)
					{
						this.GetWallType(wall);
					}
					else
					{
						RoofBase roofBase = hcSurfaceData.Host as RoofBase;
						if (roofBase != null)
						{
							this.GetRoofType(roofBase);
						}
						else
						{
							Floor floor = hcSurfaceData.Host as Floor;
							if (floor != null)
							{
								this.GetFloorType(floor);
							}
						}
					}
				}
			}
			return true;
		}

		private bool GetWallType(Wall wall)
		{
			WallType wallType = wall.WallType;
            //wallType.Kind.ToString() + ": " + wallType.Name;
			return false;
		}

		private bool GetRoofType(RoofBase roof)
		{
			RoofType roofType = roof.RoofType;
			return false;
		}

		private bool GetFloorType(Floor floor)
		{
			return false;
		}

		private bool ObtainOpenings()
		{
			return false;
		}

		private bool ApplySpaceFilter()
		{
			if (this.m_hcSpaces == null)
			{
				this.m_hcSpaces = new List<HcSpaceData>();
			}
			else
			{
				this.m_hcSpaces.Clear();
			}
			foreach (Level level in this.Levels)
			{
				List<Space> spaces = this.GetSpaces(level);
				foreach (Space space in this.m_spaceDataFilter.GetSpaces(spaces))
				{
					HcSpaceData item = new HcSpaceData(space);
					this.m_hcSpaces.Add(item);
				}
			}
			return true;
		}

		private bool SetSurfaceAdjacent(ref HcSurfaceData f1, ref HcSurfaceData f2)
		{
			return true;
		}

		private bool AddSpaceAdjacentSurface(ElementId spaceId, string sSurfaceId)
		{
			foreach (HcSpaceData hcSpaceData in this.m_hcSpaces)
			{
				if (hcSpaceData.Space.Id == spaceId)
				{
					hcSpaceData.AddSurfaceIdRef(sSurfaceId);
					break;
				}
			}
			return true;
		}

		private Document m_document;

		private List<Level> m_levels;

		private Dictionary<ElementId, List<Space>> m_spaceDictionary;

		private Dictionary<ElementId, List<Zone>> m_zoneDictionary;

		private Phase m_defaultPhase;

		private HcSpaceDataFilter m_spaceDataFilter;

		private List<HcSpaceData> m_hcSpaces;

		private List<HcSurfaceData> m_hcSurfaces;
	}
}
